Tutorial / Make a menu, switch scene, leave the game
Now that we have the draft of the first stage of our game, it's time to add a menu to quit the game or start a new game. This tutorial will teach you how to create buttons, switch between different scene and leave the game. This is also an opportunity to discover some interesting concepts for the future: the "ray" and the script properties. First button Start by creating a new scene for our main menu and set the scene as the start-up scene of your project. Add a camera and an object model with a button. Make an "exit" button model (a simple flat block with a text like texture), or get one from an existing project. For example, this one came from "Doomsday Carrot Rampage" : Now that we have our button, we have to make it useful!. Create a new script and attach it to your button object. In the function Behavior:Update(), we will constantly check if the user clicks on the button, in which case we leave the game. To check if the user left-clicks somewhere in the game window, we use the following condition: if CraftStudio.Input.WasButtonJustPressed("Fire") then ... end CraftStudio.Input.WasButtonJustPressed("Fire") will return "1" if the input named "Fire" as been pressed and "0" the rest of the time. Check in the administration tab if the input "Fire" is defined and linked to the left clic. The remaining code will take place between if and end. What remains is to determine whether the cursor is on the button the input is activated. We can get the position of the cursor with : CraftStudio.Input.GetMousePosition() Now we need to know if this point is part of the button. The easiest method is to draw an imaginary half-line starting from the camera and passing through the cursor point. To do this, CrafStudio provides a very useful tool: the ray. We can create a ray directly from the camera component with the mouse position as an argument. We begin by retrieving the "Camera" component associated with the object (here called "camera"): self.camera = CraftStudio.FindGameObject( "Camera" ):GetComponent( "Camera" ) We will create the ray using the CreateRay() method of this component : local ray = self.camera:CreateRay( mousePos ) The local variable "ray" will contain a ray starting at the camera's center and pass through the mouse position. Finally, we will check that the ray collides with our button's model (to which our script is associated) using the following condition: if ray:IntersectsModelRenderer( self.modelRndr ) ~= nil then ... end ray:IntersectsModelRenderer(model button) returns the distance between the rays's starting point and his intersection with model passed as a parameter. If this distance is not nil (i.e. if a collision exists) the button has been touched by the ray and our condition will be true. Our parameter self.modelRndr is model renderer component of the object the script is attached. It will be the button we recovered by: self.modelRndr = self.gameObject:GetComponent( "ModelRenderer" ) The last used function will the one needed to leave the game: CraftStudio.Exit() It seems quite obvious.... To make our script easier to read, we will put our declaration in Behavior:Awake() : function Behavior:Awake() self.modelRndr = self.gameObject:GetComponent( "ModelRenderer" ) self.camera = CraftStudio.FindGameObject( "camera" ):GetComponent( "Camera" ) end And the checking in Behavior:Update() : function Behavior:Update() if CraftStudio.Input.WasButtonJustPressed("Fire") then local mousePos = CraftStudio.Input.GetMousePosition() local ray = self.camera:CreateRay( mousePos ) local distance = ray:IntersectsModelRenderer( self.modelRndr ) if distance ~= nil then CraftStudio.Exit() end end end Run, test… Make several different buttons Now create a second "Play" button. This will launch our scene. To manage it could involve a new script by replacing: CraftStudio.Exit () with: CraftStudio.LoadScene (CraftStudio.FindAsset ("name of the scene play")) But if we had a lot of buttons, we would have to recreate a new script for each button ... To make life easier we will instead use a single script for all buttons! We will use a really useful feature: "script's properties". To do this, open up the script for the first button, and check "Show properties" to see the dark brown area between the script and the revision list. We will need one property so click on the "+". A new line has appeared in the "Name" box enter the name of your variable. I'll put "btnFunction" because it is the variable that will hold the button's function. In the box "Type" select "Text" and do not put anything as default value. Once done, go back to your normal scene and select your play button and just below the name of the script you should see your "btnFunction" property with a box on next. Check this box and a textbox will appear. In this box you will write what will contain the variable "btnFunction". I suggest you put a word which makes sense (if it's the play button play, do not write "ezfhyzvcyz" ^^). Therefore, fill this box for your Quit button with "quit", add the same script to your new "play" button and fill the box "btnFunction" with "play". Once done, go back to your script. We must now verify the value of "btnFunction" and trigger the corresponding action using a conventional conditional structure: If then ... elseif then ... end : if self.btnFunction "quit" then end "self." means that the variable belongs to this object. So it will different for every button. "quit" is the text that must be contained in the variable so that the action takes place. (The quotation marks are used to designate a text) And now we can use the function: CraftStudio.Exit() which leaves the game. To manage the other button, instead of "end", just put this line to load our game scene: elseif self.btnFunction "play" then CraftStudio.LoadScene (CraftStudio.FindAsset ("game")) end The entire script Here is the finished script. It works for two buttons, but you can easily add some others. It should be ok for you if you have followed and understood this tutorial. function Behavior: Awake () self.camera = CraftStudio.FindGameObject("camera"):GetComponent("Camera") self.modelRndr = self.gameObject:GetComponent("ModelRenderer") end function Behavior: Update () if CraftStudio.Input.WasButtonJustPressed("Fire") then local MousePos = CraftStudio.Input.GetMousePosition() local ray = self.camera:CreateRay(MousePos) local distance = ray:IntersectsModelRenderer(self.modelRndr) if distance ~= nil then if self.btnFunction "quit" then CraftStudio.Exit() elseif self.btnFunction "play" then CraftStudio.LoadScene(CraftStudio.FindAsset("game")) end end end end (Tutorial inspired Wardow's one)